package com.hmy.contract.service.contract.save.lease.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.hmy.contract.common.properties.TemplateSkipFieldProperties;
import com.hmy.contract.service.dto.contract.*;
import com.hmy.contract.service.dto.save.SaveLeaseContractDto;
import com.hmy.order.api.common.enums.OrderDeviceEnum;
import com.hmy.order.api.common.enums.OrderPaymentMethodEnum;
import com.hmy.order.api.common.enums.OrderPaymentPeriodEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author seven.qi 齐胜南
 * @version 1.0
 * @description
 * @date 2024/3/11 19:02
 */
@Service
@Slf4j
public class LeaseContractFieldBuildService {
    public static final String SIGNYEAR_KEY = "signYear";
    public static final String SIGNMONTH_KEY = "signMonth";
    public static final String SIGNDAY_KEY = "signDay";
    public static final String SIGNDATE_KEY = "signDate";
    public static final String CONTRACTNO_KEY = "contractNo";
    public static final String DEVICEMODEL_KEY = "deviceModel";
    public static final String DEVICENUM_KEY = "deviceNum";
    public static final String INITIALDEVICEDETAIL_KEY = "initialDeviceDetail";
    public static final String RENTALTYPE_KEY = "rentalType";
    public static final String HANDOVERTIME_KEY = "handoverTime";
    public static final String RENTALTYPE_DAY_KEY = "日租";
    public static final String RENTALTYPE_MONTH_KEY = "月租";
    public static final String ESTIMATEDTOTALAMOUNT_KEY = "estimatedTotalAmount";
    public static final String PAYMENTMETHODTYPE_KEY = "paymentMethodType";
    public static final String PAYMENTPERIODTYPE_KEY = "paymentPeriodType";
    public static final String TRANSPORTATIONMETHODTYPE_KEY = "transportationMethodType";
    public static final String TRANSPORTATIONAGREEMENTTYPE_KEY = "transportationAgreementType";
    public static final String AGREEMENTMONTH_KEY = "agreementMonth";
    private static final String AUTHORIZERNAME = "authorizerName";
    private static final String AUTHORIZERPHONE = "authorizerPhone";

    private static final String AUTHORIZERIDCARDNUMBER = "authorizerIdCardNumber";
    public static final Integer TRANSPORTATION_LESSOR = 10;
    public static final Integer TRANSPORTATION_COST_HALVE = 10;
    public static final String DAILYRENT = "dailyRent";
    public static final String MONTHLYRENT = "monthlyRent";
    public static final String GUARANTEEDEPOSIT = "guaranteeDeposit";
    public static final String ESTIMATEDRENT = "estimatedRent";
    public static final String INITIALENTRYFREIGHT = "initialEntryFreight";
    public static final String DEVICETYPE = "deviceType";

    @Resource
    private TemplateSkipFieldProperties templateSkipFieldProperties;

    public List<FieldDto> fillFieldValue(SaveLeaseContractDto createContractDto) {
        List<FieldDto> fieldDtoList = new ArrayList<>();

        fillOrderInfo(createContractDto, fieldDtoList);

        fillOrderDeviceDetail(createContractDto, fieldDtoList);

        fillOrderTransportationDetail(createContractDto, fieldDtoList);

        fillOrderInitialDeviceDetail(createContractDto, fieldDtoList);

        fillOrderAuthorizerDetail(createContractDto, fieldDtoList);


        fieldDtoList.add(FieldDto.builder().key(SIGNYEAR_KEY).value(String.valueOf(DateUtil.year(new Date(System.currentTimeMillis())))).build());
        fieldDtoList.add(FieldDto.builder().key(SIGNMONTH_KEY).value(String.valueOf(DateUtil.thisMonth() + 1)).build());
        fieldDtoList.add(FieldDto.builder().key(SIGNDAY_KEY).value(String.valueOf(DateUtil.dayOfMonth(new Date(System.currentTimeMillis())))).build());
        fieldDtoList.add(FieldDto.builder().key(SIGNDATE_KEY).value(String.valueOf(DateUtil.format(new Date(System.currentTimeMillis()), "YYYY年MM月dd日"))).build());
        fieldDtoList.add(FieldDto.builder().key(CONTRACTNO_KEY).value(createContractDto.getContractNo().substring(5)).build());
        log.debug("field list : {}", JSONUtil.toJsonPrettyStr(fieldDtoList));
        return fieldDtoList;
    }

    private void fillOrderAuthorizerDetail(SaveLeaseContractDto createContractDto, List<FieldDto> fieldDtoList) {
        List<OrderAuthorizerDto> authorizerDetails = createContractDto.getOrderInfo().getAuthorizerDetails();

        if (CollUtil.isNotEmpty(authorizerDetails)) {
            for (int i = 0; i < authorizerDetails.size(); i++) {
                if (StrUtil.isNotEmpty(authorizerDetails.get(i).getAuthorizerName())) {
                    fieldDtoList.add(FieldDto.builder().key(AUTHORIZERNAME + (i + 1)).value(authorizerDetails.get(i).getAuthorizerName()).build());
                }
                if (StrUtil.isNotEmpty(authorizerDetails.get(i).getAuthorizerPhone())) {
                    fieldDtoList.add(FieldDto.builder().key(AUTHORIZERPHONE + (i + 1)).value(authorizerDetails.get(i).getAuthorizerPhone()).build());
                }
                if (StrUtil.isNotEmpty(authorizerDetails.get(i).getAuthorizerIdCardNumber())) {
                    fieldDtoList.add(FieldDto.builder().key(AUTHORIZERIDCARDNUMBER + (i + 1)).value(authorizerDetails.get(i).getAuthorizerIdCardNumber()).build());
                }
            }
        }

    }

    protected void fillOrderInitialDeviceDetail(SaveLeaseContractDto createContractDto, List<FieldDto> fieldDtoList) {
        List<OrderInitialDeviceDetailDto> orderInitialDeviceDetails = createContractDto.getOrderInfo().getOrderInitialDeviceDetails();
        if (CollUtil.isNotEmpty(orderInitialDeviceDetails)) {
            StringBuilder str = new StringBuilder();
            for (int i = 1; i <= orderInitialDeviceDetails.size(); i++) {
                Map<String, Object> bean = BeanUtil.beanToMap(orderInitialDeviceDetails.get(i - 1));
                str.append(bean.get(DEVICEMODEL_KEY)).append("/").append(bean.get(DEVICENUM_KEY)).append("\n");
            }
            fieldDtoList.add(FieldDto.builder().key(INITIALDEVICEDETAIL_KEY).value(str.toString()).build());
        }
    }

    protected void fillOrderTransportationDetail(SaveLeaseContractDto createContractDto, List<FieldDto> fieldDtoList) {
        List<OrderTransportationDetailDto> orderTransportationDetails = createContractDto.getOrderInfo().getOrderTransportationDetails();
        if (CollUtil.isNotEmpty(orderTransportationDetails)) {
            if (orderTransportationDetails.size() == 2) {
                for (OrderTransportationDetailDto orderTransportationDetail : orderTransportationDetails) {
                    if (TRANSPORTATION_COST_HALVE.equals(orderTransportationDetail.getTransportationAgreementType())) {
                        fieldDtoList.add(FieldDto.builder().key(AGREEMENTMONTH_KEY + 1).value(orderTransportationDetail.getTransportationAgreementConstraints().toString()).build());
                    } else {
                        fieldDtoList.add(FieldDto.builder().key(AGREEMENTMONTH_KEY + 2).value(orderTransportationDetail.getTransportationAgreementConstraints().toString()).build());
                    }
                }
                StringBuilder str1 = new StringBuilder();
                str1.append("[").append(Boolean.TRUE).append(",").append(Boolean.TRUE).append("]");
                fieldDtoList.add(FieldDto.builder().key(TRANSPORTATIONAGREEMENTTYPE_KEY).value(str1.toString()).build());
            }
        }
    }

    protected void fillOrderDeviceDetail(SaveLeaseContractDto createContractDto, List<FieldDto> fieldDtoList) {
        List<OrderDeviceDetailDto> orderDeviceDetails = createContractDto.getOrderInfo().getOrderDeviceDetails();
        if (CollUtil.isNotEmpty(orderDeviceDetails)) {
            for (int i = 1; i <= orderDeviceDetails.size(); i++) {
                Map<String, Object> bean = BeanUtil.beanToMap(orderDeviceDetails.get(i - 1));
                for (String key : bean.keySet()) {
                    if (templateSkipFieldProperties.getList().contains(key) || Objects.isNull(bean.get(key))) {
                        continue;
                    }
                    if (RENTALTYPE_KEY.equalsIgnoreCase(key)) {
                        Integer rentType = (Integer) bean.get(key);
                        fieldDtoList.add(FieldDto.builder().key(key + i).value(rentType == 1 ? RENTALTYPE_DAY_KEY : RENTALTYPE_MONTH_KEY).build());
                    } else if (HANDOVERTIME_KEY.equalsIgnoreCase(key)) {
                        Date handoverTime = (Date) bean.get(HANDOVERTIME_KEY);
                        fieldDtoList.add(FieldDto.builder().key(key + i).value(DateUtil.format(handoverTime, "YYYY/MM/dd")).build());
                    } else if (DAILYRENT.equalsIgnoreCase(key)) {
                        BigDecimal dailyRent = (BigDecimal) bean.get(key);
                        fieldDtoList.add(FieldDto.builder().key(key + i).value(NumberUtil.roundStr(dailyRent.toString(), 0)).build());
                    } else if (MONTHLYRENT.equalsIgnoreCase(key)) {
                        BigDecimal monthlyRent = (BigDecimal) bean.get(key);
                        fieldDtoList.add(FieldDto.builder().key(key + i).value(NumberUtil.roundStr(monthlyRent.toString(), 0)).build());
                    }else if (DEVICETYPE.equals(key)) {
                        fieldDtoList.add(FieldDto.builder().key(key + i).value(OrderDeviceEnum.getDescByType(String.valueOf(bean.get(key)))).build());
                    } else {
                        fieldDtoList.add(FieldDto.builder().key(key + i).value(String.valueOf(bean.get(key))).build());
                    }
                }
            }
        }
    }

    protected void fillOrderInfo(SaveLeaseContractDto createContractDto, List<FieldDto> fieldDtoList) {
        Map<String, Object> map = BeanUtil.beanToMap(createContractDto.getOrderInfo());
        for (String key : map.keySet()) {
            if (templateSkipFieldProperties.getList().contains(key) || ObjectUtil.isEmpty(map.get(key))) {
                continue;
            }
            // 金额转大写
            if (ESTIMATEDTOTALAMOUNT_KEY.equalsIgnoreCase(key)) {
                BigDecimal estimatedTotalAmount = (BigDecimal) map.get(ESTIMATEDTOTALAMOUNT_KEY);
                fieldDtoList.add(FieldDto.builder().key(key).value(String.valueOf(NumberUtil.round(estimatedTotalAmount, 0))).build());
            } else if (PAYMENTMETHODTYPE_KEY.equalsIgnoreCase(key)) {
                StringBuilder str = new StringBuilder();
                int paymentMethodType = Integer.parseInt(map.get(PAYMENTMETHODTYPE_KEY).toString());
                if (paymentMethodType == OrderPaymentMethodEnum.PAYMENT_METHOD_MONTHLY_CLOSING.getCode()) {
                    str.append("[").append(Boolean.TRUE).append(",").append(Boolean.FALSE).append("]");
                } else {
                    str.append("[").append(Boolean.FALSE).append(",").append(Boolean.TRUE).append("]");
                }
                fieldDtoList.add(FieldDto.builder().key(key).value(str.toString()).build());
            } else if (PAYMENTPERIODTYPE_KEY.equalsIgnoreCase(key)) {
                StringBuilder str = new StringBuilder();
                int paymentMethodType = Integer.parseInt(map.get(PAYMENTPERIODTYPE_KEY).toString());
                if (paymentMethodType == OrderPaymentPeriodEnum.PAYMENT_PERIOD_PRE_PAYMENT.getCode()) {
                    str.append("[").append(Boolean.TRUE).append(",").append(Boolean.FALSE).append("]");
                } else {
                    str.append("[").append(Boolean.FALSE).append(",").append(Boolean.TRUE).append("]");
                }
                fieldDtoList.add(FieldDto.builder().key(key).value(str.toString()).build());
            } else if (TRANSPORTATIONMETHODTYPE_KEY.equalsIgnoreCase(key)){
                StringBuilder str = new StringBuilder();
                int transportationMethodType = Integer.parseInt(map.get(TRANSPORTATIONMETHODTYPE_KEY).toString());
                if (TRANSPORTATION_LESSOR.equals(transportationMethodType)) {
                    str.append("[").append(Boolean.TRUE).append(",").append(Boolean.FALSE).append("]");
                } else {
                    str.append("[").append(Boolean.FALSE).append(",").append(Boolean.TRUE).append("]");
                }
                fieldDtoList.add(FieldDto.builder().key(TRANSPORTATIONMETHODTYPE_KEY).value(str.toString()).build());
            } else if (ESTIMATEDRENT.equalsIgnoreCase(key)) {
                BigDecimal estimatedRent = (BigDecimal) map.get(ESTIMATEDRENT);
                fieldDtoList.add(FieldDto.builder().key(ESTIMATEDRENT).value(NumberUtil.roundStr(estimatedRent.toString(), 0)).build());
            } else if (GUARANTEEDEPOSIT.equalsIgnoreCase(key)) {
                BigDecimal guaranteeDeposit = (BigDecimal) map.get(GUARANTEEDEPOSIT);
                fieldDtoList.add(FieldDto.builder().key(GUARANTEEDEPOSIT).value(NumberUtil.roundStr(guaranteeDeposit.toString(), 0)).build());
            } else if (INITIALENTRYFREIGHT.equalsIgnoreCase(key)) {
                BigDecimal initialEntryFreight = (BigDecimal) map.get(INITIALENTRYFREIGHT);
                fieldDtoList.add(FieldDto.builder().key(INITIALENTRYFREIGHT).value(NumberUtil.roundStr(initialEntryFreight.toString(), 0)).build());
            } else{
                fieldDtoList.add(FieldDto.builder().key(key).value(String.valueOf(map.get(key))).build());
            }
        }
    }
}
